/*
 * Copyright 2010-2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.googlecode.jcimd;

import java.io.IOException;

/**
 * Represents a <a href="http://en.wikipedia.org/wiki/CIMD">CIMD</a>
 * (Computer Interface to Message Distribution) session. A session
 * is ended by calling {@link #close()} to send a logout operation.
 *
 * @author Lorenzo Dee
 */
public interface Session {

	// TODO: Split this into separate interfaces based on application types.
	// TODO: 
	// SendingSession, QueryingSession, ReceivingSession.
	// 

	/**
	 * Closes this session by sending a logout operation.
	 * @throws SessionException if an error occurs while
	 *     closing this session (i.e. error occurs while
	 *     sending a logout operation)
	 * @throws IOException if an I/O error occurs
	 */
	void close() throws IOException, SessionException;

	/**
	 * Submits a message text (in user data) to a destination address.
	 * <p>
	 * Submit in its simplest mode just passes the message text and
	 * destination address to the SMS Center, which takes care of
	 * delivery. There are, however, also some special features that
	 * may be requested with the submit operation, for example first
	 * delivery time, or message to many recipients.
	 * <p>
	 * When the application wants to submit a message, it builds the
	 * message text and places it into the parameter user data. The
	 * text is sent with other necessary parameters to the SMS Center.
	 * The SMS Center then sends the message to the MS or another
	 * application.
	 * <p>
	 * The submitted message can be identified afterwards by using a
	 * time stamp generated by the SMS Center (returned in a submit
	 * response) and the destination address.
	 *
	 * @param destinationAddress
	 * @param originatingAddress
	 * @param alphanumericOriginatingAddress
	 * @param userData
	 * @param moreMessagesToSend
	 * @param validityPeriod
	 * @param protocolIdentifier
	 * @param firstDeliveryTime
	 * @param replyPathEnabled
	 * @param statusReportRequest
	 * @param cancelEnabled
	 * @param tariffClass
	 * @param serviceDescription
	 * @param priority
	 * @return time stamp generated by the message center (in 'yyMMddHHmmss' format)
	 * @throws IOException
	 * @throws SessionException
	 */
	String submitMessage(String destinationAddress,
			String originatingAddress, String alphanumericOriginatingAddress,
			UserData userData,
			Boolean moreMessagesToSend,
			TimePeriod validityPeriod,
			Integer protocolIdentifier,
			TimePeriod firstDeliveryTime,
			Boolean replyPathEnabled,
			Integer statusReportRequest,
			Boolean cancelEnabled,
			Integer tariffClass,
			Integer serviceDescription,
			Integer priority)
	throws IOException, SessionException;
	// TODO: Provide convenience version of submitMessage that only has fewer parameters: destinationAddress, originatingAddress, userData.
	/*
	String submitMessage(
			String destinationAddress, String originatingAddress, UserData userData)
	throws IOException, SessionException;
	*/
	// TODO: Support multiple destinationAddresses and multiple return time stamps.

	/**
	 * This operation is used to request a status report for a previously
	 * submitted message.
	 * <p>
	 * An enquire message status operation can be performed independently
	 * of the status report request parameter used in the submit message
	 * operation. However, a returned status code usually indicates that
	 * the status is unknown, because the SMS Center will not keep track
	 * of statuses unless requested at submission time for performance
	 * reasons.
	 * <p>
	 * No multiple enquiries are allowed in one enquire message status
	 * message packet, so applications have to request each status report
	 * separately.
	 *
	 * @param destinationAddress
	 * @param messageCenterTimeStamp time stamp generated by the message
	 *     center (in 'yyMMddHHmmss' format). This is returned by a call
	 *     to {@link #submitMessage(String, String, String, UserData,
	 *     Boolean, TimePeriod, Integer, TimePeriod, Boolean, Integer,
	 *     Boolean, Integer, Integer, Integer) submitMessage}.
	 * @return the message status
	 * @throws IOException
	 * @throws SessionException
	 */
	MessageStatus enquireMessageStatus(
			String destinationAddress, String messageCenterTimeStamp)
	throws IOException, SessionException;

	/**
	 * This operation is used by the client (application) to retrieve a
	 * message sent to the client. The usage of this operation depends
	 * on the type of message center and type of application.
	 * <p>
	 * For the SMS Center, the usage depends on the application type.
	 * <p>
	 * The querying type of application must always poll for messages
	 * using this delivery request operation.
	 * <p>
	 * For the receiving type of application, this operation is optional
	 * as normally messages are delivered immediately to the application
	 * using the deliver message operation (020). This operation can still
	 * be useful for querying the count of messages waiting for the
	 * application.
	 * <p>
	 * This operation cannot be used by send-only applications.
	 * <p>
	 * If the response to the delivery request with mode 1 or 2 is
	 * positive, one or more deliver short message operations will follow
	 * until all the messages are delivered.
	 *
	 * @throws IOException
	 * @throws SessionException
	 */
	//int deliveryRequestNumberOfMessagesWaiting() throws IOException, SessionException;
	//Packet deliveryRequestOneMessage() throws IOException, SessionException;
	//void deliveryRequestAllMessage(MessageReceiver callback) throws IOException, SessionException;
	
	/*
	void cancelMessage(String destinationAddress, String messageCenterTimeStamp, CancelMode cancelMode) throws IOException, SessionException;
	void set(String newPassword) throws IOException, SessionException;
	String get() throws IOException, SessionException;
	void alive() throws IOException, SessionException;
	void nack() throws IOException, SessionException;
	*/
	/*
	void deliverMessage() throws IOException, SessionException;
	void deliverStatusReport() throws IOException, SessionException;
	*/

}
